﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NDde.Client;
using System.Threading;
using AAA.Meta.Quote.Data;

namespace AAA.Quote
{
    public class DDERealtimeQuote : AbstractRealtimeQuote, IDisposable
    {
        private const int TIMEOUT = 600;
        private string _strIdentifyValue;
        private string _strIdentify;
        private DdeClient _ddeClient;        
        private Thread _tTickQuote;
        private Dictionary<string, string> _dicItem;


        public DDERealtimeQuote(string strApplication, string strTopic, Dictionary<string, string> dicItem)
            : this(strApplication, strTopic, null, dicItem)
        {
        }

        public DDERealtimeQuote(string strApplication, string strTopic, string strIdentify, Dictionary<string, string> dicItem)
        {
            _strIdentify = strIdentify;
            _dicItem = dicItem;
            _ddeClient = new DdeClient(strApplication, strTopic);            
        }

        private void TickQuote()
        {
            string strIdentifyValue = "0";
            float fPreviousVolume = 0;
            float fVolume = 0;
            TickData tickData = new TickData();
            TrustData trustData = new TrustData();

            try
            {
                while (IsStarted)
                {                    
                    Thread.Sleep(QuotePeriod);
                    
                    if (_strIdentify != null)
                    {
                        strIdentifyValue = _ddeClient.Request(_strIdentify, TIMEOUT);
                        if (strIdentifyValue == _strIdentifyValue)
                            continue;
                    }

                    fVolume = float.Parse(_ddeClient.Request(_dicItem["Volume"], TIMEOUT));

                    tickData.Ticks = DateTime.Now.Ticks;
                    tickData.Date = DateTime.Now.ToString("yyyy/MM/dd");
                    tickData.Time = DateTime.Now.ToString("HH:mm:ss.fff");
                    tickData.Price = float.Parse(_ddeClient.Request(_dicItem["Price"], TIMEOUT));
                    tickData.Volume = fVolume - fPreviousVolume; ;
                    tickData.AskPrice = float.Parse(_ddeClient.Request(_dicItem["AskPrice"], TIMEOUT));
                    tickData.AskVolume = float.Parse(_ddeClient.Request(_dicItem["AskVolume"], TIMEOUT));
                    tickData.BidPrice = float.Parse(_ddeClient.Request(_dicItem["BidPrice"], TIMEOUT));
                    tickData.BidVolume = float.Parse(_ddeClient.Request(_dicItem["BidVolume"], TIMEOUT));                    
                    OnDataReceive(tickData);
                    
                    trustData.Price = tickData.Price;
                    trustData.TickVolume = tickData.Volume;
                    trustData.Volume = fVolume;
                    trustData.BuyPrice1 = tickData.BidPrice;
                    trustData.BuyVol1 = tickData.BidVolume;
                    trustData.SellPrice1 = tickData.AskPrice;
                    trustData.SellVol1 = tickData.AskVolume;
                    trustData.BuyPrice2 = float.Parse(_ddeClient.Request(_dicItem["BidPrice2"], TIMEOUT));
                    trustData.BuyVol2 = float.Parse(_ddeClient.Request(_dicItem["BidVolume2"], TIMEOUT));
                    trustData.SellPrice2 = float.Parse(_ddeClient.Request(_dicItem["AskPrice2"], TIMEOUT));
                    trustData.SellVol2 = float.Parse(_ddeClient.Request(_dicItem["AskVolume2"], TIMEOUT));
                    trustData.BuyPrice3 = float.Parse(_ddeClient.Request(_dicItem["BidPrice3"], TIMEOUT));
                    trustData.BuyVol3 = float.Parse(_ddeClient.Request(_dicItem["BidVolume3"], TIMEOUT));
                    trustData.SellPrice3 = float.Parse(_ddeClient.Request(_dicItem["AskPrice3"], TIMEOUT));
                    trustData.SellVol3 = float.Parse(_ddeClient.Request(_dicItem["AskVolume3"], TIMEOUT));
                    trustData.BuyPrice4 = float.Parse(_ddeClient.Request(_dicItem["BidPrice4"], TIMEOUT));
                    trustData.BuyVol4 = float.Parse(_ddeClient.Request(_dicItem["BidVolume4"], TIMEOUT));
                    trustData.SellPrice4 = float.Parse(_ddeClient.Request(_dicItem["AskPrice4"], TIMEOUT));
                    trustData.SellVol4 = float.Parse(_ddeClient.Request(_dicItem["AskVolume4"], TIMEOUT));
                    trustData.BuyPrice5 = float.Parse(_ddeClient.Request(_dicItem["BidPrice5"], TIMEOUT));
                    trustData.BuyVol5 = float.Parse(_ddeClient.Request(_dicItem["BidVolume5"], TIMEOUT));
                    trustData.SellPrice5 = float.Parse(_ddeClient.Request(_dicItem["AskPrice5"], TIMEOUT));
                    trustData.SellVol5 = float.Parse(_ddeClient.Request(_dicItem["AskVolume5"], TIMEOUT));
                    OnTrustDataReceive(trustData);

                    _strIdentifyValue = strIdentifyValue;
                    fPreviousVolume = fVolume;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public override string Request(string strItem)
        {
            try
            {
                return _ddeClient.Request(strItem, TIMEOUT);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return "";
        }

        public override bool StartQuote()
        {
            try
            {
                _ddeClient.Connect();
                _tTickQuote = new Thread(new ThreadStart(TickQuote));
                IsStarted = true;
                _tTickQuote.Start();
            }
            catch (Exception ex)
            {
                IsStarted = false;
                throw ex;
            }
            
            return IsStarted;
        }

        public override bool StopQuote()
        {
            try
            {
                _ddeClient.Disconnect();
                if (_tTickQuote != null)
                    _tTickQuote.Abort();

                _tTickQuote = null;

                IsStarted = !(_tTickQuote == null);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return (_tTickQuote == null);
        }

        #region IDisposable Members

        public void Dispose()
        {
            try
            {
                StopQuote();
                if (_tTickQuote != null)
                    _tTickQuote.Abort();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion
    }
}
